using Newtonsoft.Json;
using NUnit.Framework;
using WWB.DisqusSharp.Model.DisqusService;

namespace WWB.DisqusSharp.Tests.ModelSerialization
{
    [TestFixture]
    [Category("Unit Tests")]
    public class DisqusServiceWrapperTests
    {
        private string jsonError =
            " {\"message\": \"thread_id is a required argument\", \"code\": \"input-missing\", \"succeeded\": false}";
        private string jsonStringReturn = "{\"message\": \"somemessage\", \"code\": \"ok\", \"succeeded\": true}";
        string json =
            "{\"message\": [{\"id\": \"one\", \"name\": \"Number One\"}, {\"id\": \"two\", \"name\": \"Number Two\"}], \"code\": \"ok\", \"succeeded\": true}";

        [Test]
        public void Get_FakePayLoad_result_can_get_object()
        {
            var res = new DisqusServiceResultWrapper(json);
            Assert.That(res.IsError, Is.False);
            Assert.That(res.Error, Is.Null);
            var pl = res.GetPayLoadAs<FakeServicePayload[]>();
            Assert.That(res, Is.Not.Null);
            Assert.That(pl.Length, Is.EqualTo(2));
            var test = pl[0];
            Assert.That(test.Id, Is.EqualTo("one"));
            Assert.That(test.Name, Is.EqualTo("Number One"));
            test = pl[1];
            Assert.That(test.Id, Is.EqualTo("two"));
            Assert.That(test.Name, Is.EqualTo("Number Two"));
        }

        [Test]
        public void Get_Error_gets_error()
        {
            var res = new DisqusServiceResultWrapper(jsonError);
            Assert.That(res.IsError, "Should be an error!");
            Assert.That(res.Error.Message, Contains.Substring("thread_id"));
        }

        [Test]
        public void Assert_plain_string_is_not_error()
        {
            var res = new DisqusServiceResultWrapper(jsonStringReturn);
            Assert.That(res.IsError, Is.False);
            Assert.That(res.Error, Is.Null);
            Assert.That(res.GetPayLoadAs<string>(), Is.EqualTo("somemessage"));
        }

        [Test]
        public void Get_wrong_type_gets_correct_exception()
        {
            var res = new DisqusServiceResultWrapper(jsonStringReturn);
            Assert.That(res.IsError, Is.False);
            Assert.That(() => { res.GetPayLoadAs<FakeServicePayload[]>(); }, Throws.Exception.InstanceOf<DisqusServiceSerializationException<FakeServicePayload[]>>());
        }

        [Test]
        public void Can_get_as_string_and_convert_into_object()
        {
            var res = new DisqusServiceResultWrapper(json);
            Assert.That(res.IsError, Is.False);
            var payload = res.GetPayLoadAs<string>();
            Assert.That(payload, Is.Not.Null);
            var serobj = JsonConvert.DeserializeObject<FakeServicePayload[]>(payload);

            var test = serobj[0];
            Assert.That(test.Id, Is.EqualTo("one"));
            Assert.That(test.Name, Is.EqualTo("Number One"));
            test = serobj[1];
            Assert.That(test.Id, Is.EqualTo("two"));
            Assert.That(test.Name, Is.EqualTo("Number Two"));
        }

        [Test]
        public void Can_get_directly_as_string()
        {
            var res = new DisqusServiceResultWrapper<string>(jsonStringReturn);
            Assert.That(res.Payload, Is.EqualTo("somemessage"));
        }

        [Test]
        public void Can_get_directly_as_array()
        {
            var res = new DisqusServiceResultWrapper<FakeServicePayload[]>(json);
            Assert.That(res.Payload.Length, Is.EqualTo(2));

            var test = res.Payload[0];
            Assert.That(test.Id, Is.EqualTo("one"));
            Assert.That(test.Name, Is.EqualTo("Number One"));
            test = res.Payload[1];
            Assert.That(test.Id, Is.EqualTo("two"));
            Assert.That(test.Name, Is.EqualTo("Number Two"));
        }
    }
}